package com.redxiii.spike.pmi.tasks;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.SortedSet;
import java.util.TimerTask;

import net.sf.ehcache.Cache;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.redxiii.spike.api.communication.CommunicationService;
import com.redxiii.spike.api.message.Message;
import com.redxiii.spike.api.pmi.entity.Issue;
import com.redxiii.spike.api.pmi.entity.Member;
import com.redxiii.spike.pmi.HandlerSession;
import com.redxiii.spike.pmi.commons.PmiDatabase;
import com.redxiii.spike.util.core.EngineSession;

public class NewIssuesNotificator extends TimerTask {

	private static final Logger logger = LoggerFactory.getLogger(NewIssuesNotificator.class);

	private long lastIssueUpTime;
	private Cache activeMembersCache;
	
	public NewIssuesNotificator(Cache activeMembersCache) {
		this.activeMembersCache = activeMembersCache;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void run() {

		logger.trace("Checking for new issues...");
		PmiDatabase database = HandlerSession.getDatabase();
		boolean alert = lastIssueUpTime != 0;
		
		List<String> membersIds = null;
		try {
			membersIds = activeMembersCache.getKeysWithExpiryCheck();
		} catch (IllegalStateException e) {
			logger.warn("The 'activemembers' Cache is not alive");
			return;
		}
		
		Iterator<String> iterator = membersIds.iterator();
				
		long tempLastUdate = lastIssueUpTime;
		while (iterator.hasNext()) {
			String memberId = iterator.next();
			logger.debug("Checking new updates ({}) after {}", memberId, new Date(lastIssueUpTime));
			
			Member member = database.getMemberByMail(memberId);
			SortedSet<Issue> issues = database.getMyIssues(member.getId());
			
			for (Issue issue : issues) {
				tempLastUdate = Math.max(tempLastUdate, issue.getUpdatedOn().getTime());
				
				if (alert && issue.getUpdatedOn().getTime() > lastIssueUpTime) {
					logger.debug("Issue {} updated by {}", issue.getId(), issue.getMemberLastUpdate());
					
					if (issue.getMemberLastUpdate() == null || !issue.getMemberLastUpdate().equals(member)) {
						alertMember(memberId, issue);
					}
				}
			}
		}
		lastIssueUpTime = tempLastUdate;
	}
	
	private void alertMember(String memberId, Issue issue) {
		
		if (issue.getRawLastUpdate() == null || issue.getRawLastUpdate().length() == 0)
			return;
		
		StringBuilder buffer = new StringBuilder();
		
		buffer
			.append("*'")
			.append(issue.getMemberLastUpdate().getName())
			.append("'* alterou o ticket: #")
			.append(Long.toString(issue.getId()))
			.append(" - ")
			.append(issue.getSummary())
			.append("\r\n\r\n")
			.append(issue.getRawLastUpdate());
		
		CommunicationService commService = EngineSession.getCommunicationService(); 
		Message message = commService.createMessage(buffer, memberId);
		commService.post(message);
	}

}
